package com.common.baselibrary.log;

import android.text.TextUtils;
import android.util.Log;

import com.common.baselibrary.ApplicationManager;
import com.common.baselibrary.utils.SystemUtils;

/**
 * Created by zhangjianhui401 on 16/7/20.
 * 日志工具类（控制台打印、文件缓存）
 */
public class LogUtil {

    private static final String TAG = "PALog";

    public static void v(String msg) {
        v(TAG, msg);
    }

    public static void v(String TAG, String msg) {
        printLog(Log.VERBOSE, TAG, msg);
    }

    public static void vS(String TAG, String msgInfo) {
        vS(TAG, "", msgInfo);
    }

    public static void vS(String className, String methodName, String msgInfo) {
        apply(Log.VERBOSE, className, methodName, msgInfo);
    }

    public static void d(String msg) {
        d(TAG, msg);
    }

    public static void d(String TAG, String msg) {
        printLog(Log.DEBUG, TAG, msg);
    }

    public static void dS(String TAG, String msgInfo) {
        dS(TAG, "", msgInfo);
    }

    public static void dS(String className, String methodName, String msgInfo) {
        apply(Log.DEBUG, className, methodName, msgInfo);
    }

    public static void i(String msg) {
        i(TAG, msg);
    }

    public static void i(String TAG, String msg) {
        printLog(Log.INFO, TAG, msg);
    }

    public static void iS(String TAG, String msgInfo) {
        iS(TAG, "", msgInfo);
    }

    public static void iS(String className, String methodName, String msgInfo) {
        apply(Log.INFO, className, methodName, msgInfo);
    }

    public static void w(String msg) {
        w(TAG, msg);
    }

    public static void w(String TAG, String msg) {
        w(TAG, msg, null);
    }

    public static void w(String TAG, String msg, Throwable e) {
        printLog(Log.WARN, TAG, msg, e);
    }

    public static void wS(String TAG, String msgInfo) {
        wS(TAG, "", msgInfo);
    }

    public static void wS(String className, String methodName, String msgInfo) {
        apply(Log.WARN, className, methodName, msgInfo);
    }

    public static void e(String msg) {
        e(TAG, msg);
    }

    public static void e(String TAG, String msg) {
        e(TAG, msg, null);
    }

    public static void e(String TAG, String msg, Throwable e) {
        printLog(Log.ERROR, TAG, msg, e);
        saveLog(msg, e, true, false);//ERROR级别打印到本地日志文件中
    }

    public static void eS(String TAG, String msgInfo) {
        eS(TAG, "", msgInfo);
    }

    public static void eS(String className, String methodName, String msgInfo) {
        apply(Log.ERROR, className, methodName, msgInfo);
    }

    public static void s(String TAG, String msg) {
        e(TAG, msg, null);
    }

    /**
     * 立即保存所有日志：Native日志
     */
    public static void commit(String msgInfo, Throwable e) {
        printLog(Log.ERROR, "", msgInfo, e);
        saveLog(msgInfo, e, true, true);
    }

    /**
     * 非实时保存所有日志：Native日志
     */
    public static void apply(String msgInfo, Throwable e) {
        printLog(Log.ERROR, "", msgInfo, e);
        saveLog(msgInfo, e, true, false);
    }

    /**
     * 非实时保存日志
     */
    private static void apply(int logLevel, String className, String methodName, String msgInfo) {
        String messageInfo = "[" + className + "][" + methodName + "][" + msgInfo + "]";
        printLog(logLevel, "", messageInfo);
        saveLog(LogHelper.LOG_TYPE_NATIVE, logLevel, messageInfo, false);
    }

    /**
     * H5打印日志
     */
    public static void applyH5(int logLevel, String TAG, String msg) {
        printLog(logLevel, TAG, msg);
        if (logLevel >= Log.INFO) {
            saveLog(LogHelper.LOG_TYPE_H5, logLevel, msg, false);
        }
    }

    /**
     * 保存异常类型（Throwable）日志
     *
     * @param needPrintStack 是否需要打印异常堆栈
     * @param isNowSave      是否立即保存
     */
    private static void saveLog(String msgInfo, Throwable exception, boolean needPrintStack, boolean isNowSave) {
        StringBuffer stringBuffer = new StringBuffer(msgInfo);
        if (exception != null) {
            stringBuffer.append("\n" + "VersionName: " + SystemUtils.getAppVersionName(ApplicationManager.getApplicationContext()));
            stringBuffer.append("\n" + exception.toString());
            if (needPrintStack) {
                StackTraceElement[] stackTraceElements = exception.getStackTrace();
                if (stackTraceElements != null) {
                    for (StackTraceElement traceElement : stackTraceElements) {
                        stringBuffer.append("\n\t " + traceElement);
                    }
                }
                Throwable caseThrowable = exception.getCause();
                if (caseThrowable != null) {
                    String detailMsg = caseThrowable.toString();
                    stringBuffer.append("\n" + detailMsg);
                    stackTraceElements = caseThrowable.getStackTrace();
                    if (stackTraceElements != null) {
                        for (StackTraceElement traceElement : stackTraceElements) {
                            stringBuffer.append("\n\t " + traceElement);
                        }
                    }
                }
            }
        }
        saveLog(LogHelper.LOG_TYPE_NATIVE, Log.ERROR, stringBuffer.toString(), isNowSave);
    }

    /**
     * 保存日志
     *
     * @param isNowSave 是否立即保存
     */
    private static void saveLog(String logType, int logLevel, String msgInfo, boolean isNowSave) {
        if (LogHelper.NEED_WRITE) {
            if (logLevel < LogHelper.LOG_SAVE_LEVEL) {
                return;
            }
            //写日志文件到本地
            if (isNowSave) {
                LogWriterProxy.writeLogNow(logType, logLevel, msgInfo);
            } else {
                LogWriterProxy.writeLog(logType, logLevel, msgInfo);
            }
        }
    }

    /**
     * 控制台打印Log
     */
    private static void printLog(int logLevel, String TAG, String msg, Throwable e) {
        if (ApplicationManager.isDebug()) {
            StringBuffer stringBuffer = new StringBuffer();
            String elogTag = "";
            if (TextUtils.isEmpty(TAG)) {
                stringBuffer.append(msg);
                elogTag = "PALog";
            } else {
                stringBuffer.append(TAG).append(" ").append(msg);
                elogTag = TAG;
            }
            String msgInfo = stringBuffer.toString();
            if (logLevel < LogHelper.LOG_PRINT_LEVEL) {
                return;
            }
            if (logLevel == Log.VERBOSE) {
                Log.v(LogUtil.TAG, msgInfo, e);
            } else if (logLevel == Log.DEBUG) {
                Log.d(LogUtil.TAG, msgInfo, e);
            } else if (logLevel == Log.INFO) {
                Log.i(LogUtil.TAG, msgInfo, e);
            } else if (logLevel == Log.WARN) {
                Log.w(LogUtil.TAG, msgInfo, e);
            } else if (logLevel == Log.ERROR) {
                Log.e(LogUtil.TAG, msgInfo, e);
            } else {
                Log.i(LogUtil.TAG, msgInfo, e);
            }
        }
    }

    private static void printLog(int logLevel, String TAG, String msg) {
        printLog(logLevel, TAG, msg, null);
    }

    /**
     * 释放资源
     */
    public static void release() {
        LogWriterProxy.release();
    }
}

